Skip to content

feat(material): let every surface wear glass, not only Card - #240

Closed
pathscale wants to merge 2 commits into
masterfrom
feat/glass-material-axis
Closed

feat(material): let every surface wear glass, not only Card#240
pathscale wants to merge 2 commits into
masterfrom
feat/glass-material-axis

Conversation

@pathscale

Copy link
Copy Markdown
Owner

Glass was a real material with one consumer. styles/glass.ts derives twenty-five --glass-* tokens from three numbers, and the only component that could read them was Card — so an app whose panels are dialogs, drawers, popovers or a navbar could set the tokens and see nothing change.

What this does

material moves into the shared vocabulary and onto Dialog.Content, Drawer.Content, Popover.Content, Menu and Navbar. solid is the default on all of them, so this adds a capability without changing a single existing render.

The rules live in _shared/material.css, keyed on [data-material="glass"] rather than a per-component class. Card had them inline, and copying that block five more times would be six places to update the next time the glass vocabulary moves — which it already did once, from thirty-one hand-declared properties to three numbers. Card now carries the attribute too and keeps its own classes, so its appearance is unchanged while the definition is shared.

Three behaviours come along because they belong to the material rather than to any one component:

  • nested glass is flattened to a single pane (blurring already-blurred output is muddy rather than deeper, and costs a second pass)
  • prefers-reduced-transparency falls back to an opaque fill
  • so does a browser without backdrop-filter

Every --glass-* read carries a fallback. An undefined custom property makes CSS drop the whole declaration rather than fall back to an initial value, which is how a partial token set used to produce a surface with no background at all.

CardMaterial stays as a deprecated alias of Material. It is exported, it has always had exactly these two members, and removing it would break call sites for no gain.

Also: 2.5.0 could not build

*.generated.tsx is gitignored and layouts:generate only ever adds, so removing a component leaves its generated file behind, still importing the .recipe and .layout that went with it.

2.5.0 shipped with twenty-two of them, plus a twenty-third under table/. bun run check read them as components and reported "missing index.ts barrel export" for things that no longer exist; bun run build failed generating declarations. They are cleared here, and check-contracts.ts gained a stale-generated rule so the next deletion is caught at the gate with an actionable message instead of as tsc noise in a file invisible to git status.

docs/ui-usage.md also still listed Surface, GlassPanel, ScrollShadow, EmptyState and FloatingDock, all deleted. Corrected, and a Glass section added.

Verification

  • bun run check — 90/90 components pass
  • bun run build — clean (was failing on master)
  • bun test — 85/85 pass
  • docs/api-contract.md regenerated via bun run check:api -- --write

Version bumped to 2.6.0: new public API, no breaking change.

meh added 2 commits August 16, 2026 14:33
Glass was a real material with one consumer. `styles/glass.ts` derives
twenty-five `--glass-*` tokens from three numbers, and the only component that
could read them was Card, so an app whose panels are dialogs, drawers, popovers
or a navbar could set the tokens and see nothing change.

`material` moves into the shared vocabulary and onto Dialog.Content,
Drawer.Content, Popover.Content, Menu and Navbar. `solid` is the default on all
of them, so this adds a capability without changing a single existing render.

The rules live in `_shared/material.css`, keyed on `[data-material="glass"]`
rather than a per-component class. Card had them inline, and copying that block
five more times would be six places to update the next time the glass
vocabulary moves - which it already did once, from thirty-one hand-declared
properties to three numbers. Card now carries the attribute too and keeps its
own classes, so its appearance is unchanged while the definition is shared.

Three behaviours come along because they belong to the material rather than to
any one component: nested glass is flattened to a single pane, since blurring
already-blurred output is muddy rather than deeper and costs a second pass; and
both `prefers-reduced-transparency` and a browser without `backdrop-filter`
fall back to an opaque fill, because a tint with no blur behind it is a surface
you cannot read text on.

Every `--glass-*` read carries a fallback. An undefined custom property makes
CSS drop the whole declaration rather than fall back to an initial value, which
is how a partial token set used to produce a surface with no background at all.

`CardMaterial` stays as a deprecated alias of `Material`. It is exported, it has
always had exactly these two members, and removing it would break call sites for
no gain.
`*.generated.tsx` is gitignored and `layouts:generate` only ever adds, so
removing a component leaves its generated file behind, still importing the
`.recipe` and `.layout` that went with it. Nothing notices: the file is
invisible to `git status`, and the failure surfaces much later as tsc errors
inside a file nobody edited.

2.5.0 shipped with twenty-two of them. `bun run check` read them as components
and reported "missing index.ts barrel export" for things that no longer exist,
which is how the gate spent a release red for a reason that pointed nowhere,
and `bun run build` failed generating declarations. A twenty-third under
`table/` survived the first sweep because it sits in a directory that is still
alive.

Checked here because this script already walks every component directory, and
because a gate that names the actual file and says it is deletable build output
costs one line to act on.
@pathscale

Copy link
Copy Markdown
Owner Author

Superseded by #242, which now targets master directly and carries these commits. Collapsed to a single PR so the whole 2.6 line is one QA pass.

@pathscale pathscale closed this Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant